#ifndef CONNECTER_H
#define CONNECTER_H

#include "iostream"
#include "FrameBase.h"
#include "QtSerialPort/QSerialPort"

uint64_t getChangedEndian(uint8_t* pSmallBit,uint8_t bytes);


/* This file is one hardware driver which sailed on taobao.com,using for communicate with CAN network
 * Author: GDTR
 *
 * under the file, there contains the information of this connect and protocol
 *
 */
namespace canCont {

/* @brief protocol the basic protocol of the connect
 */
struct protocol{
    uint8_t head[2];
    uint8_t func;
    uint8_t data[25];
    uint8_t sum_check;
    uint8_t tail;
    void sumCheck();
};

/* @brief The connector work mode
 */
enum WorkMode{
    normal,
    cycle,
    slisence,
    cycleSlience
};

/* @brief SendParam: send protocol that configurate parameter of the connecter
 */
class SendParam:public protocol{
public:
    SendParam();
    void setWorkMode(WorkMode mode,uint8_t tbs1,uint8_t tbs2,uint16_t brp);
};

/* @brief SendFilter:config the filter of the connect
 */
class SendFilter:public protocol{
public:
    SendFilter();
    void setFilter(uint8_t num,bool open,uint32_t id,uint32_t mask);
};

/* @brief SendMain: Set the for 32 bits register of mailbox
 *        TIxR寄存器的31-24位
 *        TIxR寄存器的23-16位
 *        TIxR寄存器的15-8位	前面这么多存放id
 *        TIxR寄存器7-0位    [3:0]存放 。。。忘了见数据手册
 *        TDTxR寄存器的31-24位
 *        TDTxR寄存器的23-16位
 *        TDTxR寄存器的15-8位
 *        TDTxR寄存器7-0位
 *        TDHR寄存器31-24位DATA7
 *        TDHR寄存器的23-16位DATA6
 *        TDHR寄存器的15-8位DATA5
 *        TDHR寄存器的7-0位DATA4
 *        TDLR寄存器31-24位DATA3
 *        TDLR寄存器的23-16位DATA2
 *        TDLR寄存器的15-8位DATA1
 *        TDLR寄存器的7-0位DATA0
 */
class SendMail:public protocol
{
public:
    SendMail();
    void setMailBox(FrameSize size,uint32_t id,FrameType type,uint8_t dlc,uint8_t* pData);
};

/* @brief ResetConnecter:send reset frame to connecter
 *
 */
class SendReset:public protocol{
public:
    SendReset();
};

/* @brief SendReset:Send the clear frame to connecter
 *
 */
class SendClear:public protocol{
public:
    SendClear();
};

/* @brief ErrorType: The Error
 *
 */
enum ErrorType{
    noError
};

/* @brief ReceInfo: store the information for data received
 *
 */
struct ReceInfo{
    uint8_t filterEnNum;        // the number of enabled filter
    bool offLine;               // the connecter don't connected
    uint8_t errorRecent;
    uint8_t sendErrorNum;
    uint8_t receiveErrorNum;
    uint32_t baudrate;
    uint32_t sendCount;
    uint32_t sendSucessCount;
    uint32_t sendFailCount;
    uint32_t receiveSuccessCount;
};

/* @brief ReceiveInformation: The connecter will send information in some time interval
 *
 *
 */
class ReceiveInformation:public protocol{
public:
    ReceiveInformation(){}
    std::vector<ReceInfo> getInformation(uint8_t *data,uint32_t len);
};

/* @brief ReceData: store the data for data received
 *
 */
struct ReceData{
    bool isSucess;
    uint32_t ID;
    FrameSize size;
    FrameType type;
    uint8_t dataLen;
    FrameData frameData;
};

/* @brief ReceiveData: received data from the connecter
 *        RIR寄存器的31-24位
 *        RIR寄存器的23-16位
 *        RIR寄存器的15-8位
 *        RIR寄存器7-0位
 *        RDTR寄存器的31-24位
 *        RDTR寄存器的23-16位
 *        RDTR寄存器的15-8位
 *        RDTR寄存器7-0位
 *        RDHR寄存器31-24位DATA7
 *        RDHR寄存器的23-16位DATA6
 *        RDHR寄存器的15-8位DATA5
 *        RDHR寄存器的7-0位DATA4
 *        RDLR寄存器31-24位DATA3
 *        RDLR寄存器的23-16位DATA2
 *        RDLR寄存器的15-8位DATA1
 *        RDLR寄存器的7-0位DATA0
 */
class ReceiveData:public protocol{
public:
    ReceiveData(){}
    std::vector<ReceData> getData(uint8_t* data,uint32_t len);
};

/* @brief Connecter
 *
 */
class CAN_Connecter{
public:
    CAN_Connecter(QSerialPort& device):serial(device){};
    ~CAN_Connecter(){}

    void setParam(WorkMode mode,uint8_t tbs1,uint8_t tbs2,uint16_t brp);
    void setFilter(uint8_t num,bool open,uint32_t id,uint32_t mask);
    void sendData(FrameSize size,uint32_t id,uint8_t dlc,uint8_t* pData);
    void sendRequest(FrameSize size,uint32_t id,uint8_t dlc);
    void resetConnecter();
    void clearCount();
    std::vector<ReceInfo> receiveInfo(uint8_t* data,uint32_t len){return infoFrame.getInformation(data,len);}
    std::vector<ReceData> receiveData(uint8_t* data,uint32_t len){return receDataFrame.getData(data,len);}

private:
    QSerialPort& serial;
    SendParam sendParamFrame;
    SendFilter sendFilterFrame;
    SendMail sendDataFrame;
    SendReset sendResetFrame;
    SendClear sendClearFrame;
    ReceiveInformation infoFrame;
    ReceiveData receDataFrame;
};

} // namespace canCont



/*******************************************************************************************************
                                    USB-CAN转换器通信协议 V4.0 2019.10.29
采用串口通讯，数据长度8位，无校验，1位停止位，波特率460800。报文为30个字节的固定长度，其中由前导码0x55 0xAA，字节的和校验和结尾符0x88组成。凡是用不到的报文都用0x00填充
一、	上位机发下位机报文说明：
1.	设置参数在。功能码0x01。这些全在开始的时候设置。设置后不能改变。
    i.	工作模式4种。
        1.	正常模式0x00
        2.	环回模式0x01
        3.	静默模式0x02
        4.	环回静默模式0x03
    ii.	波特率参数4个。
        1.	tBS1 1-16    占1位
        2.	tBS2 1 -8     占1位
        3.	BRP 1-1024   占2位
    iii.	禁止自动重发1位。0：允许自动重发。1：禁止自动重发。
    各位功能
        0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20	21	22	23	24	25	26	27	28	29
        0x55	0xAA	功能码0x01	工作模式设置	tBS1	tBS2	BRP高8位	BRP低8位	0x01																	0x77	0x88	0x99	和校验	0x88

2.	滤波设置。功能码0x02
    i.	上电默认1路可接所有报文（显然其编号为0）。
    ii.	剩下13路全部工作在屏蔽位模式。
        0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20	21	22	23	24	25	26	27	28	29
        0x55	0xAA	功能码0x02	过滤器编号(0-13)	打开(1)或关闭(0)过滤器	过滤ID的31-24位	过滤ID的23-16位	过滤ID的15-8位	过滤ID的7-0位	过滤MASK的31-24位	过滤MASK的23-16位	过滤MASK的15-8位	过滤MASK的7-0位																和校验	0x88

3.	发送设置。功能码0x03
    i.	由上位机组合成需要发送的报文。可填充满发送邮箱。其中包括扩展帧标准帧的选择。
        0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20	21	22	23	24	25	26	27	28	29
        0x55	0xAA	功能码0x03	TIxR寄存器的31-24位	TIxR寄存器的23-16位	TIxR寄存器的15-8位	TIxR寄存器7-0位	TDTxR寄存器的31-24位	TDTxR寄存器的23-16位	TDTxR寄存器的15-8位	TDTxR寄存器7-0位	TDHR寄存器31-24位DATA7	TDHR寄存器的23-16位DATA6	TDHR寄存器的15-8位DATA5	TDHR寄存器的7-0位DATA4	TDLR寄存器31-24位DATA3	TDLR寄存器的23-16位DATA2	TDLR寄存器的15-8位DATA1	TDLR寄存器的7-0位DATA0										和校验	0x88
4.	发送设置。软件复位下位机。功能码0x04
        0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20	21	22	23	24	25	26	27	28	29
        0x55	0xAA	功能码0x04																										和校验	0x88
5.	清除计数。功能码0x05
        0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20	21	22	23	24	25	26	27	28	29
        0x55	0xAA	功能码0x05	1：清除所有计数2：清除发送计数																									和校验	0x88

一、	下位机发上位机报文说明
前导码改为0xAA 0x55。
1.	定时传送状态。功能码0x01和0x0其中的数据有
    a)	滤波器使能个数！
    b)	发送错误的接收错误计数！
    c)	当前波特率，精确到bps，用三个报文！！
    d)	增加发送计数（32位，而且是下位机的发送计数），发送成功计数，发送失败计数。还有发送成功失败计数和。（如果增加这个，为了相对的实时性，可能需要调整100-500ms上传状态，时间越短，系统压力就比较大。）
    e)	最近一次错误类型码。
    f)	离线状态，正常状态！！
        0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20	21	22	23	24	25	26	27	28	29
        0xAA	0x55	功能码0x01	滤波器使能个数	错误警告标志	错误被动标志	离线标志	最近一次错误代码	发送错误计数（内部）	接收错误计数（内部）	波特率的23-16位	波特率的15-8位	波特率的7-0位	发送计数的31-24位	发送计数的23-16位	发送计数的15-8位	发送计数的7-0位	成功发送计数的31-24位	成功发送计数的23-16位	成功发送计数的15-8位	成功发送计数的7-0位	失败发送计数的31-24位	失败发送计数的23-16位	失败发送计数的15-8位	失败发送计数的7-0位	工作模式	自动重发使能位		和校验	0x88
        0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20	21	22	23	24	25	26	27	28	29
        0xAA	0x55	功能码0x02	接收成功计数的31-24位	接收成功计数的23-16位	接收成功计数的15-8位	接收成功计数的7-0位																						和校验	0x88


2.	发送通过滤波器的所接收到的数据。功能码0x03。
    a)	其中包括必要的4个32位寄存器信息。X`
    b)	滤波器编号。（这个功能暂时保留）
        0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20	21	22	23	24	25	26	27	28	29
        0xAA	0x55	功能码0x03	RIR寄存器的31-24位	RIR寄存器的23-16位	RIR寄存器的15-8位	RIR寄存器7-0位	RDTR寄存器的31-24位	RDTR寄存器的23-16位	RDTR寄存器的15-8位	RDTR寄存器7-0位	RDHR寄存器31-24位DATA7	RDHR寄存器的23-16位DATA6	RDHR寄存器的15-8位DATA5	RDHR寄存器的7-0位DATA4	RDLR寄存器31-24位DATA3	RDLR寄存器的23-16位DATA2	RDLR寄存器的15-8位DATA1	RDLR寄存器的7-0位DATA0	成功接收计数值31-24位	成功接收计数值23-16位	成功接收计数值15-8位	成功接收计数值7-0位						和校验	0x88

*******************************************************************************************************/

#endif // CONNECTER_H
